package savelog;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

/**
 * Title: DataSource class for CSIS 343 Final Project 
 * Description: CS 343 Final Project - DataSource This class will handle all of the local database and file comparing calls
 * 
 * @author Erik Olson
 * @email erik.olson-5@my.uwrf.edu
 * @author Mike Harmon
 * @email michael.harmon@my.uwrf.edu
 * @author Jack Friermuth
 * @email jack.friermuth@my.uwrf.edu
 * @author Luke Vang
 * @email luke.vang@my.uwrf.edu
 * @author Casey Golla
 * @email casey.golla@my.uwrf.edu
 * @date December 4th 2012
 */
public class DataSource {
	
	//Database fields
	private static SQLiteDatabase database;
	private MySQLiteHelper dbHelper;
	
	//all of the columns for the Saves table
	private String[] savesAllColumns = {
			"save_id",
			"game_id",
			"save_descrip",
			"save_date_created",
			"save_date_logged",
			"save_src",
			"dev_id"
	};
	
	//all of the columns for the Devices table
	private String[] devicesAllColumns = {
			"dev_id",
			"dev_name"
	};
	
	//all of the columns for the Games table
	private String[] gamesAllColumns = {
		"game_id",
		"game_title",
		"game_cover",
		"dev_id",
		"sys_id"
	};
	
	//all of the columns for the Systems table
	private String[] systemsAllColumns = {
			"sys_id",
			"sys_name",
			"sys_directory",
			"sys_ext",
			"sys_is_active",
			"theme_id"
	};
	
	//all of the columns for the Themes table
	private String[] themesAllColumns = {
			"theme_id",
			"theme_text_primary",
			"theme_text_secondary",
			"theme_background_main",
			"theme_background_table"
	};
	
	/**
	 * constructor for DataSource, will create a database helper
	 * @param Context context : 	current state of the application
	 */
	public DataSource(Context context) {
		dbHelper = MySQLiteHelper.getInstance( context );
	}
	
	/**
	 * method to open a database connection
	 * @throws SQLException
	 */
	public void open() throws SQLException {
		database = dbHelper.getWritableDatabase();
	}
	
	/**
	 * method to close the database connection
	 */
	public void close() {
	    dbHelper.close();
	}
	
	/**
	 * method to delete the save that has the provided id
	 * @param int id : 		the id of the save that you want to delete
	 */
	public void deleteSave( int id ) {
		database.delete( "Saves", "save_id = " + id, null );
	}
	
	/**
	 * method to create a new save, and return the newly created save
	 * @param int game_id				:	game id for the save
	 * @param string save_descrip		:	description of the save
	 * @param string save_date_created	:	when the save was created (Y/M/D)
	 * @param string save_date_logged	:	when the save was logged in SaveLog (Y/M/D)
	 * @param string save_src			:	source path to the save files
	 * @param int dev_id				:	id of the device the save is from
	 * @return	Saves save 				:	the newly created save
	 */
	public Saves createSave( int game_id, String save_descrip, String save_date_created, String save_date_logged, String save_src, int dev_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "game_id", game_id);
		values.put( "save_descrip", save_descrip);
		values.put( "save_date_created", save_date_created);
		values.put( "save_date_logged", save_date_logged);
		values.put( "save_src", save_src);
		values.put( "dev_id", dev_id);
		
		//inserting the new record
		Integer insertID = (int)database.insert( "Saves", null, values);
		String[] idArray = {
				insertID.toString()
		};
		
		//querying for the new record
		Cursor cursor = database.query( "Saves", savesAllColumns, "save_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//turning the cursor into a save
		Saves newSave = cursorToSave( cursor );
		
		//closing the cursor
		cursor.close();
		return newSave;
	}
	
	/**
	 * method to insert a new save
	 * @param int game_id				:	game id for the save
	 * @param string save_descrip		:	description of the save
	 * @param string save_date_created	:	when the save was created (Y/M/D)
	 * @param string save_date_logged	:	when the save was logged in SaveLog (Y/M/D)
	 * @param string save_src			:	source path to the save files
	 * @param int dev_id				:	id of the device the save is from
	 */
	public void insertSave( int game_id, String save_descrip, String save_date_created, String save_date_logged, String save_src, int dev_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "game_id", game_id);
		values.put( "save_descrip", save_descrip);
		values.put( "save_date_created", save_date_created);
		values.put( "save_date_logged", save_date_logged);
		values.put( "save_src", save_src);
		values.put( "dev_id", dev_id);
		
		//inserting the new record
		database.insert( "Saves", null, values);
	}
	
	/**
	 * method to return a save that has the provided id
	 * @param int id		:	the id of the save that you want
	 * @return Saves save	: 	save that had the provided id
	 */
	public Saves getSaveById( int id ) {
		//changing the id into a string array
		String[] idArray = {
				"" + id
		};
		
		//Querying the database
		Cursor cursor = database.query( "Saves", savesAllColumns, "save_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a save
		Saves save = cursorToSave( cursor );
		
		//closing the cursor
		cursor.close();
		return save;
	}
	
	/**
	 * method to return all saves in the database
	 * @return	List saves :	a list containing all saves
	 */
	public List<Saves> getAllSaves() {
		//creating an empty arraylist to hold the saves
		List<Saves> saves = new ArrayList<Saves>();
		
		//querying the database for all of the saves
		Cursor cursor = database.query( "Saves", savesAllColumns, null, null, null, null, null);
		
		cursor.moveToFirst();
		
		//looping through all results changing them into saves and adding them to the list
		while (!cursor.isAfterLast()) {
		      Saves save = cursorToSave(cursor);
		      saves.add(save);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return saves;
	}
	
	/**
	 * method to delete the device that has the provided id
	 * @param int id : 		the id of the device that you want to delete
	 */
	public void deleteDevice( int id ) {
		database.delete( "Devices", "dev_id = " + id, null );
	}
	
	/**
	 * method to create a new device, and return the newly created device
	 * @param dev_name			:	The device name to insert
	 * @return Devices device  :	the newly created device
	 */
	public Devices createDevice( String dev_name ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "dev_name", dev_name);
		
		//inserting the new record
		Integer insertID = (int)database.insert( "Devices", null, values);
		String[] idArray = {
				insertID.toString()
		};
		
		//querying for the new record
		Cursor cursor = database.query( "Devices", devicesAllColumns, "dev_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//turning the cursor into a save
		Devices device = cursorToDevice( cursor );
		
		//closing the cursor
		cursor.close();
		return device;
	}
	
	/**
	 * method to create a new device
	 * @param dev_name			:	The device name to insert
	 * @return Devices device  :	the newly created device
	 */
	public void insertDevice( String dev_name ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "dev_name", dev_name);
		
		//inserting the new record
		database.insert( "Devices", null, values);
	}
	
	/**
	 * method to return a device that has the provided id
	 * @param int id			:	the id of the device that you want
	 * @return Devices device	: 	save that had the provided id
	 */
	public Devices getDeviceById( int id ) {
		//changing the id into a string array
		String[] idArray = {
				"" + id
		};
		
		//Querying the database
		Cursor cursor = database.query( "Devices", devicesAllColumns, "dev_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a device
		Devices device = cursorToDevice( cursor );
		
		//closing the cursor
		cursor.close();
		return device;
	}
	
	/**
	 * method to return all devices in the database
	 * @return	List device :	a list containing all devices
	 */
	public List<Devices> getAllDevices() {
		//creating an empty arraylist to hold the devices
		List<Devices> devices = new ArrayList<Devices>();
		
		//querying the database for all of the devices
		Cursor cursor = database.query( "Devices", devicesAllColumns, null, null, null, null, null);
		
		cursor.moveToFirst();
		
		//looping through all results changing them into devices and adding them to the list
		while (!cursor.isAfterLast()) {
			Devices device = cursorToDevice(cursor);
		      devices.add(device);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return devices;
	}
	
	/**
	 * method to delete the game that has the provided id
	 * @param int id : 		the id of the game that you want to delete
	 */
	public void deleteGame( int id ) {
		database.delete( "Games", "game_id = " + id, null );
	}
	
	/**
	 * method to create a new game, and return the newly created game
	 * @param game_title :		The title of the game to insert
	 * @param game_cover :		Path to the game cover
	 * @param dev_id	  :		The device id to insert
	 * @param sys_id	  :		The system the game is on
	 * @return Games game:		the newly created game
	 */
	public Games creategame( String game_title, String game_cover, int dev_id, int sys_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "game_title", game_title );
		values.put( "game_cover", game_cover );
		values.put( "dev_id", dev_id );
		values.put( "sys_id", sys_id );
		
		//inserting the new record
		Integer insertID = (int)database.insert( "Games", null, values);
		String[] idArray = {
				insertID.toString()
		};
		
		//querying for the new record
		Cursor cursor = database.query( "Games", gamesAllColumns, "game_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//turning the cursor into a game
		Games game = cursorToGame( cursor );
		
		//closing the cursor
		cursor.close();
		return game;
	}
	
	/**
	 * method to create a new game
	 * @param game_title :		The title of the game to insert
	 * @param game_cover :		Path to the game cover
	 * @param dev_id	  :		The device id to insert
	 * @param sys_id	  :		The system the game is on
	 */
	public void insertgame( String game_title, String game_cover, int dev_id, int sys_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		
		//adding new values
		values.put( "game_title", game_title );
		values.put( "game_cover", game_cover );
		values.put( "dev_id", dev_id );
		values.put( "sys_id", sys_id );
		
		//inserting the new record
		database.insert( "Games", null, values);
	}
	
	/**
	 * method to return a game that has the provided id
	 * @param int id	  :	the id of the game that you want
	 * @return Games game: 	game that had the provided id
	 */
	public Games getGameById( int id ) {
		//changing the id into a string array
		String[] idArray = {
				"" + id
		};
		
		//Querying the database
		Cursor cursor = database.query( "Games", gamesAllColumns, "game_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a game
		Games game = cursorToGame( cursor );
		
		//closing the cursor
		cursor.close();
		return game;
	}
	
	/**
	 * method to return all games in the database
	 * @return	List games :	a list containing all games
	 */
	public List<Games> getAllGames() {
		//creating an empty arraylist to hold the games
		List<Games> games = new ArrayList<Games>();
		
		//querying the database for all of the games
		Cursor cursor = database.query( "Games", gamesAllColumns, null, null, null, null, null);
		
		cursor.moveToFirst();
		
		//looping through all results changing them into games and adding them to the list
		while (!cursor.isAfterLast()) {
			Games game = cursorToGame(cursor);
		      games.add(game);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return games;
	}
	
	/**
	 * method to delete the system that has the provided id
	 * @param int id : 		the id of the system that you want to delete
	 */
	public void deleteSystem( int id ) {
		database.delete( "Systems", "sys_id = " + id, null );
	}
	
	/**
	 * method to create a new system, and return the newly created system
	 * @param string sys_name 	   :	The name of the system to insert
	 * @param string sys_directory :	The path to the system to insert
	 * @param string sys_ext	   :	The file extension of the system to insert
	 * @param int sys_is_active	   :	of the system to insert is active
	 * @param int theme_id	 	   :	The theme id of the system to insert
	 * @return Systems system      :	the newly created system
	 */
	public Systems createSystem( String sys_name, String sys_directory, String sys_ext, int sys_is_active, int theme_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "sys_name", sys_name);
		values.put( "sys_directory", sys_directory);
		values.put( "sys_ext", sys_ext);
		values.put( "sys_is_active", sys_is_active);
		values.put( "theme_id", theme_id);
		
		//inserting the new record
		Integer insertID = (int)database.insert( "Systems", null, values);
		String[] idArray = {
				insertID.toString()
		};
		
		//querying for the new record
		Cursor cursor = database.query( "Systems", systemsAllColumns, "sys_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//turning the cursor into a system
		Systems system = cursorToSystem( cursor );
		
		//closing the cursor
		cursor.close();
		return system;
	}
	
	/**
	 * method to create a new system
	 * @param string sys_name 	   :	The name of the system to insert
	 * @param string sys_directory :	The path to the system to insert
	 * @param string sys_ext	   :	The file extension of the system to insert
	 * @param int sys_is_active	   :	of the system to insert is active
	 * @param int theme_id	 	   :	The theme id of the system to insert
	 */
	public void insertSystem( String sys_name, String sys_directory, String sys_ext, int sys_is_active, int theme_id ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "sys_name", sys_name);
		values.put( "sys_directory", sys_directory);
		values.put( "sys_ext", sys_ext);
		values.put( "sys_is_active", sys_is_active);
		values.put( "theme_id", theme_id);
		
		//inserting the new record
		database.insert( "Systems", null, values);
	}
	
	/**
	 * method to return a system that has the provided id
	 * @param int id	 :	the id of the system that you want
	 * @return Systems system: 	system that had the provided id
	 */
	public Systems getSystemById( int id ) {
		//changing the id into a string array
		String[] idArray = {
				"" + id
		};
		
		//Querying the database
		Cursor cursor = database.query( "Systems", systemsAllColumns, "sys_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a system
		Systems system = cursorToSystem( cursor );
		
		//closing the cursor
		cursor.close();
		return system;
	}
	
	/**
	 * method to return all systems in the database
	 * @return	List systems :	a list containing all systems
	 */
	public List<Systems> getAllSystems() {
		//creating an empty arraylist to hold the systems
		List<Systems> systems = new ArrayList<Systems>();
		
		//querying the database for all of the systems
		Cursor cursor = database.query( "Systems", systemsAllColumns, null, null, null, null, null);
		
		cursor.moveToFirst();
		
		//looping through all results changing them into systems and adding them to the list
		while (!cursor.isAfterLast()) {
			Systems system = cursorToSystem(cursor);
		      systems.add(system);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return systems;
	}
	
	/**
	 * method to delete the theme that has the provided id
	 * @param int id : 		the id of the theme that you want to delete
	 */
	public void deletetheme( int id ) {
		database.delete( "Themes", "theme_id = " + id, null );
	}
	
	/**
	 * method to create a new theme, and return the newly created theme
	 * @param string theme_text_primary     :	The primary text theme to insert
	 * @param string theme_text_secondary   :	The secondary text theme to insert
	 * @param string theme_background_main  :	The main background theme to insert
	 * @param string theme_background_table :	The table background theme to insert
	 * @return Themes theme      		    :	the newly created theme
	 */
	public Themes createTheme( String theme_text_primary, String theme_text_secondary, String theme_background_main, String theme_background_table ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "theme_text_primary", theme_text_primary);
		values.put( "theme_text_secondary", theme_text_secondary);
		values.put( "theme_background_main", theme_background_main);
		values.put( "theme_background_table", theme_background_table);
		
		//inserting the new record
		Integer insertID = (int)database.insert( "Themes", null, values);
		String[] idArray = {
				insertID.toString()
		};
		
		//querying for the new record
		Cursor cursor = database.query( "Themes", themesAllColumns, "theme_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//turning the cursor into a theme
		Themes theme = cursorToTheme( cursor );
		
		//closing the cursor
		cursor.close();
		return theme;
	}
	
	/**
	 * method to create a new theme
	 * @param string theme_text_primary     :	The primary text theme to insert
	 * @param string theme_text_secondary   :	The secondary text theme to insert
	 * @param string theme_background_main  :	The main background theme to insert
	 * @param string theme_background_table :	The table background theme to insert
	 */
	public void insertTheme( String theme_text_primary, String theme_text_secondary, String theme_background_main, String theme_background_table ) {
		//object to hold the new values
		ContentValues values = new ContentValues();
		//adding new values
		values.put( "theme_text_primary", theme_text_primary);
		values.put( "theme_text_secondary", theme_text_secondary);
		values.put( "theme_background_main", theme_background_main);
		values.put( "theme_background_table", theme_background_table);
		
		//inserting the new record
		database.insert( "Themes", null, values);
	}
	
	/**
	 * method to return a theme that has the provided id
	 * @param int id	 :	the id of the theme that you want
	 * @return Themes theme: 	theme that had the provided id
	 */
	public Themes getThemeById( int id ) {
		//changing the id into a string array
		String[] idArray = {
				"" + id
		};
		
		//Querying the database
		Cursor cursor = database.query( "Themes", themesAllColumns, "theme_id=?", idArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a theme
		Themes theme = cursorToTheme( cursor );
		
		//closing the cursor
		cursor.close();
		return theme;
	}
	
	/**
	 * method to return all Themes in the database
	 * @return	List Themes :	a list containing all Themes
	 */
	public List<Themes> getAllThemes() {
		//creating an empty arraylist to hold the Themes
		List<Themes> themes = new ArrayList<Themes>();
		
		//querying the database for all of the Themes
		Cursor cursor = database.query( "Themes", themesAllColumns, null, null, null, null, null);
		
		cursor.moveToFirst();
		
		//looping through all results changing them into Themes and adding them to the list
		while (!cursor.isAfterLast()) {
			Themes theme = cursorToTheme(cursor);
		      themes.add(theme);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return themes;
	}
	
	/**
	 * This function will grab all games and order them by title
	 * @return List Games :		list containing all games sorted by title
	 */
	public List<Games> getGamesSortedByGameTitle() {
		//creating an empty arraylist to hold the games
		List<Games> games = new ArrayList<Games>();
		
		//querying the database for all of the games, ordering by game title
		String sql = "SELECT " +
				"			*" +
				"	  FROM   " +
				"			Games" +
				"	  ORDER BY " +
				"			game_title COLLATE NOCASE ASC";
		Cursor cursor = database.rawQuery( sql, new String[] {} );
		
		cursor.moveToFirst();
		
		//looping through all results changing them into games and adding them to the list
		while (!cursor.isAfterLast()) {
			Games game = cursorToGame(cursor);
		      games.add(game);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
		return games;
	}
	
	/**
	 * Method to get all saves that are for a perticular game
	 * @param int id 	   :	The game id you want saves for
	 * @return List saves :		A list of saves that the game has
	 */
	public List<Saves> getSavesByGameID( int id ) {
		//creating an empty arraylist to hold the saves
		List<Saves> saves = new ArrayList<Saves>();
		
		//querying the database for all of the saves
		String sql = "SELECT " +
				"		*" +
				"	  FROM" +
				"		Saves" +
				"	  WHERE" +
				"		game_id=?";
		Cursor cursor = database.rawQuery( sql, new String[] { "" + id } );
		
		cursor.moveToFirst();
		
		//looping through all results changing them into saves and adding them to the list
		while (!cursor.isAfterLast()) {
		      Saves save = cursorToSave(cursor);
		      saves.add(save);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
	    return saves;
	}
	
	/**
	 * Method to get the latest save for a game
	 * @param int id	   :		The id of the game you want the latest save for
	 * @return Saves save :			The save 
	 */
	public Saves getLatestSaveForGame( int id ) {		
		//querying the database for latest save for game with game_id = id
		String sql = "SELECT " +
				"		*, MAX(save_date_created)" +
				"	  FROM" +
				"		Saves" +
				"	  WHERE" +
				"		game_id=?";
		
		Cursor cursor = database.rawQuery( sql, new String[] { "" + id } );
		cursor.moveToFirst();
		
		//changing the cursor into a save
		Saves save = cursorToSave( cursor );
		
		//closing the cursor
		cursor.close();
		return save;
	}
	
	/**
	 * Method to get all games on a system
	 * @param int id 	    :		The id of the system you want games for
	 * @return List Games  :		List containing all games for the system with the provided id
	 */
	public List<Games> getGamesOnSystem( int id ) {
		List<Games> games = new ArrayList<Games>();
		
		//Querying the database
		String sql = "SELECT" +
				"		*" +
				"	  FROM" +
				"		Games" +
				"	  WHERE" +
				"		sys_id = ?";
		Cursor cursor = database.rawQuery( sql, new String[] { "" + id } );
		cursor.moveToFirst();
		
		//looping through all results changing them into saves and adding them to the list
		while (!cursor.isAfterLast()) {
		      Games game = cursorToGame(cursor);
		      games.add(game);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
		return games;
	}
	
	/**
	 * method to remove all entries from the database
	 */
	public void removeAllEntries() {
		database.delete( "Saves", null, null );
		database.delete( "Games", null, null );
		database.delete( "Themes", null, null );
		database.delete( "Devices", null, null );
		database.delete( "Systems", null, null );
	}
	
	/**
	 * method to change a cursor into a theme
	 * @param Cursor cursor	  :	cursor to be changed into a theme
	 * @return Themes theme:	the theme that was in the cursor
	 */
	private Themes cursorToTheme( Cursor cursor ) {
		//creating a blank theme
		Themes theme = new Themes();
		
		//adding the values from the cursor to the theme
		theme.setTheme_id( cursor.getInt( 0 ) );
		theme.setTheme_text_primary( cursor.getString( 1 ) );
		theme.setTheme_text_secondary( cursor.getString( 2 ) );
		theme.setTheme_background_main( cursor.getString( 3 ) );
		theme.setTheme_background_table( cursor.getString( 4 ) );
		return theme;
	}
	
	/**
	 * method to change a cursor into a system
	 * @param Cursor cursor	  :	cursor to be changed into a system
	 * @return systems system:	the system that was in the cursor
	 */
	private Systems cursorToSystem( Cursor cursor ) {
		//creating a blank system
		Systems system = new Systems();
		
		//adding the values from the cursor to the system
		system.setSys_id( cursor.getInt( 0 ) );
		system.setSys_name( cursor.getString( 1 ) );
		system.setSys_directory( cursor.getString( 2 ) );
		system.setSys_ext( cursor.getString( 3 ) );
		system.setSys_is_active( cursor.getInt( 4 ) );
		system.setTheme_id( cursor.getInt( 5 ) );
		return system;
	}
	
	/**
	 * method to change a cursor into a game
	 * @param Cursor cursor	  :	cursor to be changed into a game
	 * @return Games game    :	the game that was in the cursor
	 */
	private Games cursorToGame( Cursor cursor ) {
		//creating a blank game
		Games game = new Games();
		
		//adding the values from the cursor to the game
		game.setGame_id( cursor.getInt( 0 ) );
		game.setGame_title( cursor.getString( 1 ) );
		game.setGame_cover( cursor.getString( 2 ) );
		game.setDev_id( cursor.getInt( 3 ) );
		game.setSys_id( cursor.getInt( 4 ) );
		return game;
	}
	
	/**
	 * method to change a cursor into a save
	 * @param Cursor cursor:	cursor to be changed into a save
	 * @return Saves save	:	the save that was in the cursor
	 */
	private Saves cursorToSave( Cursor cursor ) {
		//creating a blank save
		Saves save = new Saves();
		
		//adding the values from the cursor to the save
		save.setSave_id( cursor.getInt( 0 ) );
		save.setGame_id( cursor.getInt( 1 ) );
		save.setSave_descrip( cursor.getString( 2 ) );
		save.setSave_date_created( cursor.getString( 3 ) );
		save.setSave_date_logged( cursor.getString( 4 ) );
		save.setSave_src( cursor.getString( 5 ) );
		save.setDev_id( cursor.getInt( 6 ) );
		return save;
	}
	
	/**
	 * method to change a cursor into a device
	 * @param Cursor cursor	  :	cursor to be changed into a device
	 * @return Devices device:	the device that was in the cursor
	 */
	private Devices cursorToDevice( Cursor cursor ) {
		//creating a blank device
		Devices device = new Devices();
		
		//adding the values from the cursor to the device
		device.setDev_id( cursor.getInt( 0 ) );
		device.setDev_name( cursor.getString( 1 ) );
		return device;
	}
	
	public static List<Games> BubbleSort( List<Games> games ) {
	     int j;
	     boolean flag = true;   // set flag to true to begin first pass
	     Games temp;   //holding variable

	     while ( flag ) {
	            flag= false;    //set flag to false awaiting a possible swap
	            for( j=0;  j < games.size()  -1;  j++ ) {
	                   if ( games.get( j ).getGame_title().compareTo( games.get( j+1 ).getGame_title() ) < 0 ) {
	                           temp = games.get( j );                //swap elements
	                           games.set( j, games.get( j +1 ) );
	                           games.set( j +1, temp );
	                           flag = true;              //shows a swap occurred  
	                  } 
	            } 
	      } 
	     return games;
	} 
	
	/**
	 * Method to loop through all active systems grab all save and game files in each directory for that system and
	 * then check if any of the save or game files need to be added to the database
	 * 
	 * @param List systems			 :		list of active systems
	 * @param String path_to_backup :		path to the backup folder
	 * @param boolean use_covers	 :		if we are using game covers
	 */
	public void checkGamesAndSaves( List<Systems> systems, String path_to_backup, boolean use_covers ) {
		//looping through all active systems
		for( Systems system : systems ) {
			//getting all saves and games
			List<File> saves = getListFiles( new File( system.getSys_directory() ), system.getSys_ext() );

			//determining the game extension for the system
			String game_extension;
			String system_name = system.getSys_name();
			if( true == system_name.equals( "SNES" ) ) {
				game_extension = "zip";
			} else if( true == system_name.equals( "N64" ) ) {
				game_extension = "v64";
			} else if( true == system_name.equals( "SEGA" ) ) {
				game_extension = "bin";
			} else if( true == system_name.equals( "GBA" ) ) {
				game_extension = "GBA";
			} else if( true == system_name.equals( "Nintendo" ) ) {
				game_extension = "bin";
			} else {
				game_extension = "zip";
			}

			List<File> games = getListFiles( new File( system.getSys_directory() ), game_extension );
			
			//checking if any game needs to be added
			for( File game : games ) {
				//splitting the name because we only care about the name not the extension
				String[] gameNameParts = game.getName().split("\\.");
				String gameTitle = gameNameParts[0];
				
				//checking if any games have this name
				Games game_by_title = getGameByTitle( gameTitle );
				
				if( 0 == game_by_title.getGame_id() ) {
					//game doens't exist in db, check if it has a save
					
					//checking if the game has a save associated with it
					boolean name_found = false;
					for( File save : saves ) {
						//splitting the save name to get rid of the extension
						String[] saveNameParts = save.getName().split("\\.");
						String saveTitle = saveNameParts[0];
						
						//checking if save name is the same as the game name
						if( true == saveTitle.equals( gameTitle ) ) {
							name_found = true;
						}
					}
					
					//if game has save then add game to db
					if( true == name_found ) {
						
						//check if we should provide the path for the game cover
						String game_cover = "";
						if( true == use_covers ) {
							game_cover = system.getSys_directory();
						}
						
						//insert game
						insertgame( gameTitle, game_cover, 0, system.getSys_id() );
					}
				}
			}
			
			//checking if any saves need to be added
			for( File save : saves ) { 
				//spliting the name to get rid of the extension
				String[] saveNameParts = save.getName().split("\\.");
				String saveTitle = saveNameParts[0];
				
				//getting when the save was last modified down to the millisecond
				String last_modifed =  new SimpleDateFormat("yyyy/MM/dd k:m:s:S").format( save.lastModified() ); //format is year/month/day hour:minute:second:millisecond
				
				//check if any saves have this date
				if( false == saveDateCreatedExists( last_modifed ) ) {
					//save is not in the database so lets add it
					
					//getting the current date
					Date date = new Date();
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd k:m:s:S");
					
					//getting the game the save is for
					Games game_by_title = getGameByTitle( saveTitle );

					//inserting the save
					Saves insert_save = createSave( game_by_title.getGame_id(), "Save added on " + sdf.format(date), last_modifed, sdf.format(date), "" , 0 ); 
					
					//getting the system the save is for
					Systems save_system = getSystemById( game_by_title.getSys_id() );
					
					updateSaveSource( path_to_backup + "/" + save_system.getSys_name() +"_BACKUP/" + game_by_title.getGame_title() + "_" + save_system.getSys_id() + "_" + insert_save.getSave_id() +  "." + save_system.getSys_ext(), insert_save.getSave_id() );
			
					//copying the file to the backup directory
					copyfile( save.getAbsolutePath(),  path_to_backup + "/" + save_system.getSys_name() +"_BACKUP/" + game_by_title.getGame_title() + "_" + save_system.getSys_id() + "_" + insert_save.getSave_id() +  "." + save_system.getSys_ext() );
				}
			}
		}
	}
	
	/**
	 * Method to get a save by its save date created
	 * @param String date :		The date you want to look for
	 * @return Saves save :		The save that has the provided date
	 */
	public Saves getSaveBySaveDateCreated( String date ) {
		//changing the date into a string array
		String[] dateArray = {
				"" + date
		};
		
		//Querying the database
		Cursor cursor = database.query( "Saves", savesAllColumns, "save_date_created=?", dateArray, null, null, null );
		cursor.moveToFirst();
		
		//changing the cursor into a theme
		Saves save = cursorToSave( cursor );
		
		//closing the cursor
		cursor.close();
		return save;
	}
	
	/**
	 * Method to check if a game exists by title
	 * @param String title			 :		The title you want to look for
	 * @return boolean title_exists :		If the title exists in the database
	 */
	public boolean gameExistsByTitle( String title ) {
		//getting all saves
		List<Games> games = getAllGames();
		
		//setting up a boolean
		boolean title_exists = false;
		
		//looping through all games checking if any of them have the provided title
		for( Games game : games ) {
			if( game.getGame_title().equals( title ) ) {
				title_exists = true;
			}
		}
		
		return title_exists;
	}
	
	/**
	 * Method to set a save as the save being used
	 * @param Saves save :		The save you want set to the active one
	 */
	public void swapFile( Saves save, String path_to_backup ) {
		//getting the game the system is for
		Games game = getGameById( save.getGame_id() );
		
		//getting the system the game is for
		Systems system = getSystemById( game.getSys_id() );
		
		//determining the locations
		String backup_file_location = save.getSave_src();
		String destination_location = system.getSys_directory() + "/" + game.getGame_title() + "." + system.getSys_ext();
		
		//copying the file
		copyfile( backup_file_location, destination_location );
		
		//updating the save date created for the save
		File file = new File( destination_location );
		String last_modifed =  new SimpleDateFormat("yyyy/MM/dd k:m:s:S").format( file.lastModified() );
		updateSaveDateCreated( last_modifed, save.getSave_id() );
	}
	
	/**
	 * Method to get the files that have the provided extension in the provided directory
	 * @param File parentDir	  :		A file of the directory
	 * @param String file_ending :		The file extension you want
	 * @return List inFiles		  : 	A list of the files that have the provided extension in the provided directory
	 */
	private List<File> getListFiles(File parentDir, String file_ending) {
		//creating an empty list to hold the files we want
	    ArrayList<File> inFiles = new ArrayList<File>();
	    
	    //getting all files in the directory
	    File[] files = parentDir.listFiles();
	    
	    //looping through all files adding the ones that have the correct file extension to the inFiles list
	    for (File file : files) {
	    	if(file.getName().toLowerCase().endsWith("." + file_ending.toLowerCase())){
                inFiles.add(file);
            }
	    }
	    return inFiles;
	}
	
	/**
	 * Method to update the source directory path for a system
	 * @param String new_path :		new source path for the system
	 * @param int sys_id	   :	id of the system to update
	 */
	public void updateSystemSource( String new_path, int sys_id ) {
		//sql string to update the system with the provided id
		String sql = "UPDATE " +
					"		Systems " +
					" SET" +
					"  		sys_directory = ? "+
					" WHERE" +
					"  		sys_id = ?;";
		
		//putting the parameters into an array
		String[] paramArray = {
				"" + new_path,
				"" + sys_id
		};
		
		//updating the system
		Cursor cursor = database.rawQuery( sql, paramArray );
		
		//cleaning up the cursor
		cursor.moveToFirst();
		cursor.close();
	}
	
	/**
	 * Method to update the source directory path for a save
	 * @param String new_path :		new source path for the save
	 * @param int sys_id	   :	id of the save to update
	 */
	public void updateSaveSource( String new_path, int save_id ) {
		//sql string to update the system with the provided id
		String sql = "UPDATE " +
					"		Saves " +
					" SET" +
					"  		save_src = ? "+
					" WHERE" +
					"  		save_id = ?;";
		
		//putting the parameters into an array
		String[] paramArray = {
				"" + new_path,
				"" + save_id
		};
		
		//updating the save
		Cursor cursor = database.rawQuery( sql, paramArray );
		
		//cleaning up the cursor
		cursor.moveToFirst();
		cursor.close();
	}
	
	/**
	 * Method to update the save date created for a save with the provided id
	 * @param String date :		the new save date created
	 * @param int save_id :		the id of the save to update
	 */
	public void updateSaveDateCreated( String date, int save_id ) {
		//sql string to update the save with the provided id
		String sql = "UPDATE " +
					"		Saves " +
					" SET" +
					"  		save_date_created = ? "+
					" WHERE" +
					"  		save_id = ?;";
		
		//putting the parameters into an array
		String[] paramArray = {
				"" + date,
				"" + save_id
		};
		
		//updating the save
		Cursor cursor = database.rawQuery( sql, paramArray );
		
		//cleaning up the cursor
		cursor.moveToFirst();
		cursor.close();
	}
	
	/**
	 * method to get a game by its game title
	 * @param String title :		title you want to look for
	 * @return Games game  :		the game that has the provided title
	 */
	public Games getGameByTitle( String title ) {
		//changing the title into a string array
		String[] titleArray = {
				"" + title
		};
		
		//Querying the database
		Cursor cursor = database.query( "Games", gamesAllColumns, "game_title=?", titleArray, null, null, null );
		cursor.moveToFirst();
		
		//checking if we got a game back
		Games game;
		if( cursor.getCount() != 0 ) {
			//changing the cursor into a game
			game = cursorToGame( cursor );
		} else {
			//we didn't get a game so using the default constructor
			game = new Games();
		}
		
		//closing the cursor
		cursor.close();
		return game;		
	}
	
	/**
	 * method to see if a save exists by date created
	 * @param String date					:		the date you want to look for, yyyy/MM/dd k:m:s:S
	 * @return boolean date_created_exists :		true/false for if there is a save with the provided date
	 */
	public boolean saveDateCreatedExists( String date ) {
		//getting all saves
		List<Saves> saves = getAllSaves();
		
		//setting up a boolean
		boolean date_created_exists = false;
		
		//looping through all saves checking if any of them have the provided date
		for( Saves save : saves ) {
			if( save.getSave_date_created().equals( date ) ) {
				date_created_exists = true;
			}
		}
		
		return date_created_exists;
	}

	/**
	 * Method to copy a file from one location to another
	 * @param String sourcerFilePath	  :		path to the source file, including the file name and extension
	 * @param String destinationFilePath :		path to wear you want the source file copied, including the file name and extension
	 */
	public static void copyfile(String sourcerFilePath, String destinationFilePath){
		try{
			//opening the files
			File sourcerFile = new File(sourcerFilePath);
			File destinationFile = new File(destinationFilePath);
			
			//creating input and output streams
			InputStream in = new FileInputStream(sourcerFile);
			OutputStream out = new FileOutputStream(destinationFile);
	
			//setting up a buffer
			byte[] buf = new byte[1024];
			int len;
			//looping through the contents of the source file and writing them to the destination file
			while ((len = in.read(buf)) > 0){
			  out.write(buf, 0, len);
			}
			
			//closing the streams
			in.close();
			out.close();
		} catch(FileNotFoundException ex){
		} catch(IOException e){   
		}
	}
	
	/**
	 * Method to get all games on a system sorted by game title
	 * @param int id	   :		Id of system you want games for
	 * @return List games :			All games for that system sorted by game title
	 */
	public List<Games> getGamesOnSystemAZ( int id ) {
		List<Games> games = new ArrayList<Games>();
		
		//Querying the database
		String sql = "SELECT" +
				"		*" +
				"	  FROM" +
				"		Games" +
				"	  WHERE" +
				"		sys_id = ?"+
				"	  ORDER BY" +
				"		game_title COLLATE NOCASE ASC";
		Cursor cursor = database.rawQuery( sql, new String[] { "" + id } );
		cursor.moveToFirst();
		
		//looping through all results changing them into games and adding them to the list
		while (!cursor.isAfterLast()) {
		      Games game = cursorToGame(cursor);
		      games.add(game);
		      cursor.moveToNext();
		}
		
		//closing the cursor
		cursor.close();
		return games;
	}
	
}

